package com.gwq.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gwq.base.ResponseData;
import com.gwq.computedUtils.NewExercise;
import com.gwq.computedUtils.NewOperationBase;
import com.gwq.dto.ComputedDto;
import com.gwq.dto.ExercisesDto;
import com.gwq.entity.*;
import com.gwq.mapper.ComputedMapper;
import com.gwq.mapper.EquationRecordMapper;
import com.gwq.mapper.ExDateMapper;
import com.gwq.param.ExDateParam;
import com.gwq.param.ExEqualsParam;
import com.gwq.param.ExerciseParam;
import com.gwq.service.*;
import com.gwq.utils.DateUtils;
import com.gwq.utils.FileUtils;
import com.gwq.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.security.Principal;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ComputedServicelmpl extends ServiceImpl<ComputedMapper, Equation> implements ComputedService {

    @Autowired
    private ComputerService computerService;
    @Autowired
    private EquationRecordService equationRecordService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private ExercisesService exercisesService;
    @Autowired
    private ExDateMapper exDateMapper;
    @Autowired
    private EquationRecordMapper equationRecordMapper;

    @Override
    public ExercisesDto example(ExerciseParam exerciseParam,Principal principal) {

        SysUser sysUser = sysUserService.getByUserName(principal.getName());


        NewExercise newExercise = new NewExercise();
        NewOperationBase newOperationBase = new NewOperationBase();
        if(exerciseParam.getExType()==1){  //产生加法
//            newExercise.generateAdditionExercise(exerciseParam.getNumber());//未用算式基
            newExercise = newOperationBase.generateAdditionExercise(exerciseParam.getNumber(),1);//算式基生成
        }else if(exerciseParam.getExType()==2){ //产生减法
//            newExercise.GenerateSubstractExercise(exerciseParam.getNumber());  //未用算式基
            newExercise = newOperationBase.generateAdditionExercise(exerciseParam.getNumber(),2);//算式基生成
        }else{ //产生混合
//            newExercise.generateBinaryExercise(exerciseParam.getNumber());  //未用算式基
            newExercise = newOperationBase.generateAdditionExercise(exerciseParam.getNumber(),3); //算式基生成
        }


        List<ComputedDto> computedDtoArrayList = new ArrayList<>();
        List<Equation> equations = new ArrayList<>();
        newExercise.getOperationList().stream().forEach(t->{
            Equation equation = new Equation();
            ComputedDto computedDto = new ComputedDto();
            equation.setId(StringUtils.uuid());
            equation.setLeftOperand(t.getLeft_operand());
            equation.setOperator(t.getOperator());
            equation.setRightOperand(t.getRight_operand());
            equation.setCreatedAt(DateUtils.getYyyyMMddHHmmss(new Date()));
            equation.setSum(t.getValue());
            equations.add(equation);
            computedDto.setId(equation.getId());
            computedDto.setExample(t.asString());
            computedDtoArrayList.add(computedDto);
        });

        ExercisesDto exercisesDto = new ExercisesDto();

        String strExercises = JSON.toJSONString(computedDtoArrayList);

        Exercises exercises = exercisesService.addExercises(strExercises,sysUser);

        exercisesDto.setId(exercises.getId());
        exercisesDto.setComputedDtos(computedDtoArrayList);

        computerService.addEx(equations,exercises.getId()); //入库采用异步方式


        return exercisesDto;
    }

    //用户答案以及批改
    @Override
    public ResponseData exEquals(ExEqualsParam exEqualsParam, Principal principal) {

        if(StringUtils.isEmpty(exEqualsParam.getId())){
            return ResponseData.fail("还未生成算式，请先生成算式");
        }

        SysUser sysUser = sysUserService.getByUserName(principal.getName());
        List<String> ids = exEqualsParam.getComputedDtos().stream().map(t->t.getId()).collect(Collectors.toList());
        Map<String,ComputedDto> sumMap = exEqualsParam.getComputedDtos().stream().collect(Collectors.toMap(ComputedDto::getId,equation -> equation));

        Exercises exercises = exercisesService.getExercisesById(exEqualsParam.getId());

        if(exEqualsParam.getSubmitType()==1){
            QueryWrapper<EquationRecord> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("exercises_id",exercises.getId());
            equationRecordMapper.delete(queryWrapper);
        }

        /*if(exercises==null||exercises.getExercisesStatus()==1){
            return ResponseData.fail("作业已批改请勿重复提交");
        }*/

        List<Equation> equations = this.baseMapper.selectBatchIds(ids);
        AtomicReference<Integer> checkNum = new AtomicReference<>(0);
        if(equations!=null){
            List<EquationRecord> equationRecords = new ArrayList<>();
            equations.stream().forEach(o->{
                EquationRecord equationRecord = new EquationRecord();
                BeanUtils.copyProperties(o,equationRecord);
                if(sumMap.get(o.getId())!=null){

                    ComputedDto equation = sumMap.get(o.getId());
                    equationRecord.setSum(equation.getSum());
                    equationRecord.setCreatedBy(sysUser.getId());
                    equationRecord.setExercisesId(exercises.getId());
                    equationRecord.setCreatedAt(DateUtils.getYyyyMMddHHmmss(new Date()));
                    equationRecord.setTrueSum(o.getSum());
                    //判断答案对错
                    if(equation.getSum()==o.getSum()){
                        equationRecord.setRightOrWrong(1);
                    }else{
                        equationRecord.setRightOrWrong(0);
                        checkNum.getAndSet(checkNum.get() + 1);
                    }
                }
                equationRecords.add(equationRecord);
            });
            equationRecordService.addEquationRecord(equationRecords);
        }

        Integer count = ids.size()-checkNum.get();

        Integer fen = 100/ids.size();

        Integer checkCount = count*fen;

        exercises.setExercisesStatus(1);
        exercises.setOverDate(exEqualsParam.getOverDate());
        exercises.setCheckCount(checkCount);
        exercisesService.updateExercises(exercises);  //将习题集改为已修改

        return ResponseData.success("作业批改完成，请查看分数",checkCount);
    }

    @Override
    public void exSettingDate(ExDateParam exDateParam, Principal principal) {
        SysUser sysUser = sysUserService.getByUserName(principal.getName());
        if(exDateParam.getId()==null) {
            ExDate exDate = new ExDate();
            exDate.setSetDate(exDateParam.getSetDate());
            exDate.setCreatedBy(sysUser.getId());
            exDate.setCreatedAt(DateUtils.getYyyyMMddHHmmss(new Date()));
            exDateMapper.insert(exDate);
        }else{
            ExDate exDate = exDateMapper.selectById(exDateParam.getId());
            if(exDate!=null){
                exDate.setSetDate(exDateParam.getSetDate());
                exDate.setUpdatedAt(DateUtils.getYyyyMMddHHmmss(new Date()));
                exDate.setUpdatedBy(sysUser.getId());
            }
        }
    }

    @Override
    public ExDate getExDate() {
        QueryWrapper<ExDate> queryWrapper = new QueryWrapper<>();
        ExDate exDate = exDateMapper.selectOne(queryWrapper);
        if(exDate==null){
            return null;
        }
        return exDate;
    }

    @Override
    public ResponseData upload(MultipartFile verticalPicture, Principal principal) throws IOException {

        SysUser sysUser = sysUserService.getByUserName(principal.getName());

        if(verticalPicture.isEmpty()){
            ResponseData.fail("文件为空!");
        }
        String OriginalFilename = verticalPicture.getOriginalFilename();//获取原文件名

        Exercises exercises = exercisesService.getFileName(OriginalFilename);
        if(exercises==null){
            return ResponseData.fail("此文件不存在，请不要更改文件名称!");
        }


        String s = "";
        InputStreamReader in = new InputStreamReader(new FileInputStream(FileUtils.multipartFileToFile(verticalPicture)),"UTF-8");
        BufferedReader br = new BufferedReader(in);
        StringBuffer content = new StringBuffer();
        int i=0;
        List<String> exList=new ArrayList<>();
        while ((s=br.readLine())!=null){
            if(i!=0) {
                Pattern p = Pattern.compile("\\s*|\t|\r|\n"); // 去除多个空格，去除制表符，回车，换行
                Matcher m = p.matcher(s);
                s = m.replaceAll("");

                String[] ex = s.split(";");
                exList.addAll(Arrays.asList(ex));
            }
            i++;
        }

        QueryWrapper<Equation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("exercises_id",exercises.getId());

        List<Equation> equations = list(queryWrapper);
        List<EquationRecord> equationRecords = new ArrayList<>();
        AtomicReference<Integer> checkNum = new AtomicReference<>(0);
        equations.stream().forEach(o->{
            EquationRecord equationRecord = new EquationRecord();

            equationRecord.setLeftOperand(o.getLeftOperand());
            equationRecord.setRightOperand(o.getRightOperand());
            equationRecord.setOperator(o.getOperator());

            String eq =o.getLeftOperand()+""+o.getOperator()+o.getRightOperand();

            for(int k=0;k<exList.size();k++){

                String exEq = exList.get(k).substring(0,exList.get(k).indexOf("="));
                String sum = exList.get(k).substring(exList.get(k).indexOf("=")+1,exList.get(k).length());

                if(eq.equals(exEq)){
                    if(!StringUtils.isEmpty(sum)&&Integer.parseInt(sum)==o.getSum()){

                        equationRecord.setSum(Integer.parseInt(sum));
                        //判断答案对错
                        equationRecord.setRightOrWrong(1);
                    }else{
                        equationRecord.setRightOrWrong(0);
                        checkNum.getAndSet(checkNum.get() + 1);
                    }
                    equationRecord.setCreatedBy(sysUser.getId());
                    equationRecord.setExercisesId(exercises.getId());
                    equationRecord.setCreatedAt(DateUtils.getYyyyMMddHHmmss(new Date()));
                    equationRecord.setTrueSum(o.getSum());

                }
            }

            /*exList.stream().forEach(t->{
                String exEq = t.substring(0,t.indexOf("="));
                String sum = t.substring(t.indexOf("=")+1,t.length());
                if(eq.equals(exEq)){
                    if(!StringUtils.isEmpty(sum)&&Integer.parseInt(sum)==o.getSum()){

                        equationRecord.setSum(Integer.parseInt(sum));
                        //判断答案对错
                        equationRecord.setRightOrWrong(1);
                    }else{
                        equationRecord.setRightOrWrong(0);
                        checkNum.getAndSet(checkNum.get() + 1);
                    }
                    equationRecord.setCreatedBy(sysUser.getId());
                    equationRecord.setExercisesId(exercises.getId());
                    equationRecord.setTrueSum(o.getSum());

                }
            });*/
            equationRecords.add(equationRecord);
        });
        equationRecordService.addEquationRecord(equationRecords);

        Integer count = equations.size()-checkNum.get();

        Integer fen = 100/equations.size();

        Integer checkCount = count*fen;

        exercises.setExercisesStatus(1);
        exercises.setCheckCount(checkCount);
        exercisesService.updateExercises(exercises);  //将习题集改为已修改

        return ResponseData.success("作业批改完成，请前往习题集查看具体详情",checkCount);

    }


}
